home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 24 / develop Issue 24 code / Scriptable Database 1.0a15 / Database / DBProperty.h < prev    next >
Encoding:
Text File  |  1996-04-25  |  10.1 KB  |  299 lines  |  [TEXT/CWIE]

  1. //================================================================================
  2. // Greg Anderson
  3. // db+
  4. //
  5. // Cursor to a data record
  6. // 16 May 1994
  7. //================================================================================
  8. #pragma once
  9.  
  10. #ifndef __DBPROPERTYRECORD__
  11. #define __DBPROPERTYRECORD__
  12.  
  13. #include "DBRecord.h"
  14.  
  15. //
  16. // Fields
  17. //
  18. //        Flags
  19. //            b31-b29:    Used by AbstractDBRecord
  20. //            b28:        Clear (Set = object record)
  21. //            b27:        Set = data record (Clear = some other record)
  22. //            b26-b16:    Reserved
  23. //            b15-b8:     Encoded data type
  24. //             b7-b0:        Length of data stored in this record
  25. //                            Strings have a range of 0-12
  26. //                            Structures have a range of 0-8
  27. //                            Length byte is 0 if length is implicit (e.g. single longword) or not applicable (array of properties)
  28. //                            Length byte is 255 if data stored externally
  29. //        Parent sibling (or parent element for property at top of tree)
  30. //        Left sibling
  31. //        Right sibling
  32. //        Property ID
  33. //
  34. //        Three more longwords of data
  35. //            Data or index of record at top of element tree
  36. //            Data or index of record at top of property tree
  37. //            Data or type of data
  38. //
  39. //        Examples:
  40. //
  41. //        Longword
  42. //            Data
  43. //            Unused
  44. //            Type of data (kLongType)
  45. //
  46. //        Short string
  47. //            Zero to twelve bytes, length encoded in ID of flags word
  48. //
  49. //        Short typed structure
  50. //            Zero to eight bytes, length encoded in ID of flags word
  51. //            Type of data
  52. //
  53. //        Reference to longer string, array or structure
  54. //            Reference to data record (data record knows its own size)
  55. //            Unused
  56. //            Type of external data
  57. //            
  58. //        Array of arbitrary data (implemented as a record that contains properties of its own)
  59. //            Unused
  60. //            Reference to record at top of property tree
  61. //            Type of data (kListType)
  62. //
  63. //        Array of elements (implemented as a record that contains elements)
  64. //            Reference to record at top of element tree
  65. //            Unused
  66. //            Type of data (kRecordType)
  67. //
  68.  
  69. enum
  70. {
  71.     kPropertyIDWord = kIDOrParentElementIndex,
  72.     kFirstDataWord,
  73.     kSecondDataWord,
  74.     kThirdDataWord,
  75.     kExternalDataIndex = kFirstDataWord,
  76.     kTypeOfPropertyData = kThirdDataWord
  77. };
  78.  
  79. //
  80. // Constants for record flags
  81. //
  82. enum
  83. {
  84.     kDataTypeShift = 8,
  85.     kInternalLengthShift = 0
  86. };
  87.  
  88. const long kDataTypeMask = 0x0000FF00L;
  89. const long kInternalLengthMask = 0x000000FFL;
  90. const long kDataStoredExternally = kInternalLengthMask;
  91.  
  92. //
  93. // Encoded data types
  94. //
  95. enum
  96. {
  97.     //
  98.     // A "null" type means that there is no data in the property
  99.     //
  100.     kEncodedNullType = 0,
  101.     
  102.     //
  103.     // More general sets of data are also supported.  A property record
  104.     // may contain a set of properties OR a set of subtrees.  Sets are
  105.     // ordered by tree-insertion-order (by property ID or name), and may
  106.     // be iterated over.
  107.     //
  108.     // Property sets claim to be of type "list".
  109.     // Element sets claim to be of type "record".
  110.     //
  111.     kSetOfProperties,
  112.     kSetOfElements,
  113.     
  114.     //
  115.     // An external typed structure is a chunk of data whose type
  116.     // is stored in the property record, but whose data is stored
  117.     // in an external data block (because its length is greater than
  118.     // 12 bytes for strings or 8 bytes for other types).
  119.     //
  120.     // An interal typed structure is a chunk of data stored inside
  121.     // the property record itself.
  122.     //
  123.     kEncodedTypedStructure,
  124.     
  125.     //
  126.     // Well-known data types:
  127.     //
  128.     // Currently, there is only one well-known data type:  a string.
  129.     // The purpose for having a well-known type is to avoid wasting
  130.     // four bytes in the property record just to store the data type.
  131.     // The data type is instead encoded in the "type" field of the
  132.     // record word.  Thus, well-known types can be up to 12 bytes long
  133.     // before they must use external data storage, wheras other types
  134.     // can only be 8 bytes long.  (n.b. it is unnecessary to have well
  135.     // known types for data types that will always be 8 bytes or less,
  136.     // e.g. long integers, or for data types that will always be
  137.     // greater than 12 bytes in length, e.g. pictures).
  138.     //
  139.     kFirstWellKnownType,
  140.     kEncodedSmallStringType,
  141.     kLastWellKnownType
  142. };
  143.  
  144. //
  145. // Data types that we know about; these constants are the
  146. // same as those defined in AppleEvents.h, but I didn't want
  147. // to depend on Macintosh header files here, so I redefined
  148. // the constants since the set of known types is small.
  149. //
  150. enum
  151. {
  152.     kNullType                    = 'null',            // typeNull
  153.     kLongType                    = 'long',            // typeLongInteger
  154.     kListType                    = 'list',            // typeAEList
  155.     kRecordType                    = 'reco',            // typeAERecord
  156.     kStringType                    = 'TEXT'            // typeChar
  157. };
  158.  
  159. class TDBElement;
  160.  
  161. //================================================================================
  162. // Class TDBProperty
  163. //================================================================================
  164. class TDBProperty : public TDBRecord
  165. {
  166.     //
  167.     // A DBElement needs to maul a DBProperty that is added to it.
  168.     //
  169.     friend class TDBElement;
  170.     
  171.     //
  172.     // ----- Fields --------------------------------------------------------------
  173.     //
  174. protected:
  175.     AConst<TDataRecord>            fExternalData;
  176.     
  177.     //
  178.     // ----- Methods -------------------------------------------------------------
  179.     //
  180.  
  181. public:
  182.                                 TDBProperty(TDatabaseDocument* doc, long recordIndex) :
  183.                                     TDBRecord(doc, recordIndex) {};
  184.     virtual                        ~TDBProperty();
  185.     
  186.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  187.     // Methods of TAbstractRecord:
  188.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  189.  
  190. public:
  191.  
  192.     virtual void                FreeOwnedData(TTransaction* t);
  193.  
  194. protected:
  195.  
  196.     virtual const TDBProperty* DBPropertyRecord() const { return this; };
  197.  
  198.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  199.     // Methods of TDBRecord:
  200.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  201.  
  202. public:
  203.  
  204.     virtual void                InitializeNewRecord(TTransaction* t);
  205.     virtual CompareEnumeration    CompareSortKeys(TTransaction* t, AConst<TDBRecord>) const;
  206.     virtual Boolean                RecordCanHaveElements(TTransaction* t) const;
  207.     virtual Boolean                RecordCanHaveProperties(TTransaction* t) const;
  208.     virtual void                RemoveFromTree(TTransaction* t);    
  209.     
  210.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  211.     // Public interface: const methods
  212.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  213.  
  214. public:
  215.  
  216.     long                        PropertyID(TTransaction* t) const { return this->GetRecordData(t, kPropertyIDWord); };
  217.     long                        GetDataType(TTransaction* t) const;
  218.     long                        GetDataLength(TTransaction* t) const;
  219.     
  220.     long                        GetLongData(TTransaction* t) const;
  221.     void                        GetTypedData(TTransaction* t, TAbstractDataReference& data) const;
  222.     CompareEnumeration            Compare(TTransaction* t, const TAbstractDataReference& compareWith) const;
  223.     CompareEnumeration            Compare(TTransaction* t, AConst<TDBProperty> compareWith) const;
  224.     Boolean                        Contains(TTransaction* t, const TAbstractDataReference& searchFor) const;
  225.     Boolean                        Contains(TTransaction* t, AConst<TDBProperty> compareWith) const;
  226.     
  227.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  228.     // Public interface: non-const methods
  229.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  230.  
  231.     void                        SetPropertyID(TTransaction* t, long newValue) { this->ChangeRecordData(t, kPropertyIDWord, newValue); this->ResortThisRecord(t); };
  232.  
  233.     void                        MakeEmpty(TTransaction* t);
  234.     void                        SetLongData(TTransaction* t, long newValue);
  235.     void                        SetTypedData(TTransaction* t, const TAbstractDataReference& data);
  236.  
  237.     //
  238.     // Do debugging tests on this node
  239.     //
  240.     virtual void                Verify(TTransaction* t, Boolean verifyDeep = false) const;
  241.  
  242.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  243.     // Protected interface: const methods
  244.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  245.  
  246. protected:
  247.  
  248.     long                        GetEncodedDataType(TTransaction* t) const        { return ((this->RecordFlags(t) & kDataTypeMask) >> kDataTypeShift); }
  249.     long                        GetInternalDataLength(TTransaction* t) const    { return ((this->RecordFlags(t) & kInternalLengthMask) >> kInternalLengthShift); }
  250.     Boolean                        OwnsExternalData(TTransaction* t) const            { return this->GetInternalDataLength(t) == kDataStoredExternally; }
  251.     long                        GetStoredDataType(TTransaction* t) const        { return this->GetRecordData(t, kTypeOfPropertyData); }
  252.     long                        GetExternalDataIndex(TTransaction* t) const        { return this->GetRecordData(t, kExternalDataIndex); }
  253.     
  254.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  255.     // Protected interface: non-const methods
  256.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  257.  
  258. public:
  259.  
  260.     //
  261.     // Called by the external data record if it moves around
  262.     // 
  263.     void                        SetExternalDataIndex(TTransaction* t, long externalDataIndex);
  264.     
  265. protected:
  266.  
  267.     void                        SetEncodedDataType(TTransaction* t, long encodedType)            { this->SetRecordFlags(t, (this->RecordFlags(t) & ~kDataTypeMask) | ((encodedType << kDataTypeShift) & kDataTypeMask)); }
  268.     void                        SetInternalDataLength(TTransaction* t, long internalLength)        { this->SetRecordFlags(t, (this->RecordFlags(t) & ~kInternalLengthMask) | ((internalLength << kInternalLengthShift) & kInternalLengthMask)); }
  269.     void                        SetOwnsExternalData(TTransaction* t, Boolean doesOwnExternal)    { this->SetInternalDataLength(t, doesOwnExternal ? kDataStoredExternally : 0); }
  270.     void                        SetStoredDataType(TTransaction* t, long newStoredType)            { this->ChangeRecordData(t, kTypeOfPropertyData, newStoredType); }
  271.     
  272.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  273.     // Private methods:
  274.     //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  275.  
  276. private:
  277.     
  278.     AConst<TDataRecord>            ExternalData(TTransaction* t) const;
  279.     AnUpdate<TDataRecord>        UpdateExternalData(TTransaction* t);
  280.     void                        InformOwnerPropertyValueChanged(TTransaction* t) const;
  281.     TConstDataReference            PropertyDataReference(TTransaction* t) const;
  282. };
  283.  
  284. //================================================================================
  285. // Class TDataRecordComparisonObject
  286. //================================================================================
  287. class TDataRecordComparisonObject : public TAbstractDBComparisonObject
  288. {
  289. private:
  290.     long                            fSearchKey;
  291.     
  292. public:
  293.                                     TDataRecordComparisonObject(long searchKey) : fSearchKey(searchKey) {};
  294.  
  295.     virtual CompareEnumeration        TestObject(TTransaction*, AConst<TDBRecord>);
  296. };
  297.  
  298. #endif
  299.